/**
 * Copyright (c) 2012-2013 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */
package com.nokia.example.fuelcalculator.l10n;

import java.util.Calendar;
import java.util.Date;
import javax.microedition.global.Formatter;
import javax.microedition.global.ResourceException;
import javax.microedition.global.ResourceManager;

/**
 * Localizer class works as a middle layer in between the application logic
 * and JSR-238 implementation.
 */
public final class Localizer {
    private static final String RESOURCE_BASE = "L10NIDs";
    private static final String FALLBACK_LOCALE = "en";
    private static final int FALLBACK_DECIMALS_IN_DOUBLE = 2;
    private static Localizer instance;
    private static final String[] RIGHT_TO_LEFT = {
        "ar", // Arabic
        "az", // Azerbaijani
        "he", // Hebrew
        "jv", // Javanese
        "ks", // Kashmiri
        "ml", // Malayalam
        "ms", // Malay
        "pa", // Panjabi
        "fa", // Persian
        "ps", // Pushto
        "sd", // Sindhi
        "so", // Somali
        "tk", // Turkmen
        "ug", // Uighur
        "ur", // Urdu
        "yi"  // Yiddish
    };  
    
    private Formatter formatter;
    private ResourceManager resources;

    /**
     * Private constructor to prevent instantiation in an unintended way.
     */
    private Localizer() {
        try {
            formatter = new Formatter();
        } catch (Exception e) {
            formatter = new Formatter(FALLBACK_LOCALE);
        }
        
        try {
            resources = ResourceManager.getManager(
                    RESOURCE_BASE);
        } catch (Exception e) {
            resources = ResourceManager.getManager(
                    RESOURCE_BASE, FALLBACK_LOCALE);
        }
    }

    /**
     * Return singleton instance of the Localizer.
     * @return Localizer
     */
    static public Localizer getInstance() {
        if (instance == null) {
            instance = new Localizer();
        }
        return instance;
    }

    /**
     * Returns a localized String associated with an id, if there is one.
     * @param id number to a String resource
     * @return String
     */
    public String getString(int id) {
        String retval;
        try {
            retval = resources.getString(id);
        } catch (ResourceException re) {
            retval = "UNLOCALIZED id=" + id;
        }
        return retval;
    }

    /**
     * Returns the consumption with two decimal numbers.
     * @param consumption in double precision
     * @return String
     */
    public String formatConsumption(double consumption) {
        return formatter.formatNumber(consumption, getDecimalsInDouble());
    }

    /**
     * Returns date as formatted by local rules.
     * @param date
     * @return String representation of the date
     */
    public String formatDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return formatter.formatDateTime(cal, Formatter.DATE_SHORT);
    }
    
    /**
     * Returns software release date as formatted by local rules.
     * @return String representation of the release date
     */
    public String formatReleaseDate() {
        Calendar cal = Calendar.getInstance();
        int year;
        int month;
        int day;
        
        try {
            year = Integer.parseInt(getString(L10NIDs.ABOUT_VIEW_RELEASE_DATE_YEAR));
            // in Java, january is month number zero
            month = Integer.parseInt(getString(L10NIDs.ABOUT_VIEW_RELEASE_DATE_MONTH)) -1 ;
            day = Integer.parseInt(getString(L10NIDs.ABOUT_VIEW_RELEASE_DATE_DAY));
            
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.MONTH, month);
            cal.set(Calendar.DAY_OF_MONTH, day);
            
        } catch (NumberFormatException nfe) {
            // nothing meaningful to do here
        }
             
        return formatter.formatDateTime(cal, Formatter.DATE_SHORT);
    }

    /**
     * Returns true if system language is right-to-left fashioned
     * @return boolean
     */
    public boolean phoneLanguageIsRTL() {      
        String locale = System.getProperty("microedition.locale");

        for (int index = 0; index < RIGHT_TO_LEFT.length; index++) {
            if (locale.indexOf(RIGHT_TO_LEFT[index]) != -1) {
                return true;
            }
        }
        return false;
    }   
    
    /**
     * Returns the amount of decimals that should be used in consumption.
     * Although the localized variable is a number, it is represented as
     * a String in the localization resource file.
     * @return int
     */
    private int getDecimalsInDouble() {
        int retval;
        try {
            retval = Integer.parseInt(getString(L10NIDs.DECIMALS_IN_DOUBLE));
        } catch (NumberFormatException nfe) {
            retval = FALLBACK_DECIMALS_IN_DOUBLE;
        }
        return retval;
    }
}
